package analyzer;

import Util.SortedHashtable;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import org.objectweb.proactive.ActiveObjectCreationException;
import org.objectweb.proactive.Body;
import org.objectweb.proactive.ProActive;
import org.objectweb.proactive.Service;
import org.objectweb.proactive.core.config.ProActiveConfiguration;
import org.objectweb.proactive.core.node.NodeException;
import org.objectweb.proactive.core.node.NodeFactory;
import org.objectweb.proactive.ext.migration.Destination;
import org.objectweb.proactive.ext.migration.MigrationStrategyImpl;

import event.Event;
import Bloques.*;
import event.*;
import principal.AgentMessageReceiver;
import principal.StreetControllerAgent;
import principal.agentFrame;


public class AnalyzerAgent implements org.objectweb.proactive.RunActive,
java.io.Serializable {
	private boolean onItinerary = false;
	private boolean initialized;
	private transient agentFrame myFrame;
	private AgentMessageReceiver controler;
	private AnalyzerAgent otherLightControlAgent;
	private javax.swing.ImageIcon face;
	private org.objectweb.proactive.ext.migration.MigrationStrategy myStrategy;
	private org.objectweb.proactive.ext.migration.MigrationStrategyManager myStrategyManager;
	private int index;
	private String name;
	private String[] itinerary;
        int VERDE = 1;
	int ROJO = 0;
	int AMBAR =3;

	int SE =1 ; //Stop Event
	int CE =  2;//Cross Event
	int LCE = 3; //Light Change Event
	
	int CLE = 5; //Change Lane Event
	int CLEE = 6; //Change Lane End Event
	int ALE = 7; //Arrival Link Event
	int LLE = 8; //Leave Link Event
	int BE = 9; //Begin Event
	int AE= 10; //Arrival Event
	int WSE = 11; //Warning Event, as a stop event, but dont stop
	int WBE = 12; // warning Event, as a begin event, but actually for a dont stop event
        
        private String pathLog="c:/temp/log.txt";
     
        public SortedHashtable elementsInAnalysis;
           
        String objectID;
            double evTime;
            int segment;
            double evPos;
            int evType;
            
    private StreetControllerAgent streetControllerAgent;

    private int n;

    private double t;
	
	public AnalyzerAgent() {
	}

	public AnalyzerAgent(Integer ind) {
		this.index = ind.intValue();
		this.name = "Analyzer Agent" + index;
                elementsInAnalysis = new SortedHashtable();
		
	}

	public void loop() {
		rebuild();
	}

	public void rebuild() {
		Body body = ProActive.getBodyOnThis();
		myFrame = new agentFrame(face, body.getNodeURL(), index);
		
		sendMessageToControler("I just got in node " +
				ProActive.getBodyOnThis().getNodeURL());
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
		}
	}

	public void clean() {
		if (myFrame != null) {
			myFrame.dispose();
			myFrame = null;
		}
	}

	public String toString() {
		return this.name;
	}

	public void initialize(String[] s) {
		try {
			//With this we can load the image from the same location than
			//the classes
			ClassLoader cl = this.getClass().getClassLoader();
			//java.net.URL u = cl.getResource(
			//      "org/objectweb/proactive/examples/penguin/PenguinSmall.jpg");
			java.net.URL u = cl.getResource("Resources/analyzer.jpg");
			face = new javax.swing.ImageIcon(u);
		} catch (Exception e) {
			e.printStackTrace();
		}
		myStrategyManager = new org.objectweb.proactive.ext.migration.MigrationStrategyManagerImpl((org.objectweb.proactive.core.body.migration.Migratable) org.objectweb.proactive.ProActive.getBodyOnThis());
		myStrategyManager.onDeparture("clean");
		myStrategy = new MigrationStrategyImpl();
		itinerary = s;
		for (int i = 0; i < s.length; i++)
			myStrategy.add(s[i], null);
	}

	public void setControler(AgentMessageReceiver c) {
		this.controler = c;
		this.initialized = true;
	}

	public void setOther(AnalyzerAgent carGenerator) {
		this.otherLightControlAgent = carGenerator;
	}

	public Destination nextHop() {
		Destination r = myStrategy.next();
		if (r == null) {
			myStrategy.reset();
			r = myStrategy.next();
		}
		return r;
	}

	public void runActivity(Body b) {
           
            
            
            Service service = new Service(b);
		if (!initialized) {
			service.blockingServeOldest();
		}
		rebuild();
		Destination r = null;
		
		//ponerEvento(segmento,tiempo,tipo,objeto,posicion,desiredStatus,lane)
               
		 
                
                while (b.isActive()) {
			while (service.hasRequestToServe()) {
				service.serveOldest();
			}
			if (onItinerary) {
                            
                        //this.getDensityFlowLog_ver1(1,10.0,132.0,"c:/temp/logQD_ver1.txt");
                        this.getDensityFlowLog_ver2(1,10.0,"c:/temp/logQD_ver2_Calle1.txt");
                        this.getDensityFlowLog_ver2(3,10.0,"c:/temp/logQD_ver2_Calle3.txt");
                            
                             this.onItinerary = false;
                 
		          
                
                        }
				
			 else {
				// service.blockingServeOldest();
			}
		}
	}

	public String[] getItinerary() {
		return itinerary;
	}

	public void setItinerary(String[] newItinerary) {
		sendMessageToControler("I changed my itinerary", java.awt.Color.blue);
		myStrategy = new MigrationStrategyImpl();
		itinerary = newItinerary;
		for (int i = 0; i < newItinerary.length; i++)
			myStrategy.add(newItinerary[i], null);
	}

	public void start() {
		sendMessageToControler("I am starting my itinerary",
				new java.awt.Color(0, 150, 0));
		myStrategy.reset();
		onItinerary = true;
               
	}
	public void listo(){
		onItinerary = true;
		System.out.println("listo");
	}
	public void suspend() {
		if (!onItinerary) {
			sendMessageToControler("I'm already suspended");
		} else {
			sendMessageToControler("I suspended my itinerary",
					java.awt.Color.red);
			onItinerary = false;
		}
	}

	public void resume() {
		if (onItinerary) {
			sendMessageToControler("I'm already on my itinerary");
		} else {
			sendMessageToControler("I'm resuming my itinerary",
					new java.awt.Color(0, 150, 0));
			onItinerary = true;
		}
	}

	public String call() {
		return "[" + name + "] : I am working on node " +
		ProActive.getBodyOnThis().getNodeURL();
	}

	public void chainedCall() {
		if (otherLightControlAgent != null) {
			sendMessageToControler("I'm calling my peer agent");
			otherLightControlAgent.chainedCall();
		} else {
			sendMessageToControler("I don't have a peer agent to call");
		}
	}

	private void sendMessageToControler(String message) {
		if (controler != null) {
			controler.receiveMessage("[" + name + "] : " + message);
		}
	}

	private void sendMessageToControler(String message, java.awt.Color color) {
		if (controler != null) {
			controler.receiveMessage("[" + name + "] : " + message, color);
		}
	}

	public void getDensityFlowLog_ver1(int segToAnalyze,double p,double measurementArea,String pathOut){
             BufferedReader entrada = null;
            
  String[] result;
            
            double limitPeriod = p;    
            double q=0,d = 0;
            double nQ = 0,nD = 0;
            
           
            
            File f = new File( pathLog);
               
                try {
                    entrada = new BufferedReader(new FileReader(f));
                } catch (FileNotFoundException ex) {
                    ex.printStackTrace();
                }
    if ( f.exists() )
		
                    try {
                      
                         FileOutputStream out = new FileOutputStream(pathOut,true);		
			
			PrintWriter miArchivo = new PrintWriter(out);
			miArchivo.write("Densidad" +"\t"); 
			miArchivo.write("Flujo" +"\t");
			
			
			miArchivo.println();
			miArchivo.close();
                        
                        System.out.println( entrada.readLine()); 
                  
                       
                        
                        String s;
                        while((s=entrada.readLine())!= null){
                            //Separar campos
                             result = s.split(",");
                             objectID = result[0];
                             System.out.println(objectID);
                             evTime = Double.valueOf(result[1]).doubleValue();
                             segment = Integer.valueOf(result[2]).intValue();
                             evPos = Double.valueOf(result[3]).doubleValue();
                             evType = Integer.valueOf(result[4]).intValue();
                             if(segment == segToAnalyze) {
                                
                                 while(evTime > limitPeriod){
                                     
                                     nD = getNumberOfIIA();
                                     d = nD / measurementArea;
                                      out = new FileOutputStream("c:/temp/logQD_ver1.txt",true);		
			
			 miArchivo = new PrintWriter(out);
			miArchivo.write(d +"\t"); 
			miArchivo.write(q +"\t");
			
			
			miArchivo.println();
			miArchivo.close();
			
                                    //log d y q
                                     q = 0;
                                     limitPeriod = limitPeriod + p;
                              }
                              if(evType == CE){
                                      System.out.println(objectID);    
                                     if(searchIIA(objectID)!= false){
                                             removeIIA(objectID);
                                             nQ++;
                                             q= nQ / p;
                                             
                                         }
                               }else{
                                    if(evType == ALE || evType == AE){
                                         //System.out.println(objectID); 
                                        if(searchIIA(objectID)== false){
                                            addIIA(objectID);
                                        }
                                    }
                               }
                                 
                             }
                             
                        }    
                        System.out.println("Finished Analysis");
                        
                        
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    } 
        }
        public boolean removeIIA(Object itemID){
            elementsInAnalysis.remove(itemID);
            return true;
        }
        
	public boolean addIIA(Object itemID){
            // System.out.println(itemID); 
            elementsInAnalysis.put(itemID,0.0);
            return true;
        }

    public int getNumberOfIIA() {
        return elementsInAnalysis.size();

    }

    public boolean searchIIA(Object itemID) {
      boolean b=false;
        try {
            b = elementsInAnalysis.containsKey(itemID);
        } catch(NullPointerException ex) {
            System.out.println("itemID is null");
        }
        
      return b;
    }

public void getDensityFlowLog_ver2(int segToAnalyze,double p,String pathOut){
             BufferedReader entrada = null;
            
             String[] result;
            
            double limitPeriod = p;    
            double q=0,d = 0;
            //variables que almacenan la densidad y el flujo
            double nQ = 0,nD = 0;
            //variables que almacenan el numero de vehiculos que han cruzado nQ
            // y numero de vehiculos que han llegado nD
            
           
            
            File f = new File( pathLog);
               
                try {
                    entrada = new BufferedReader(new FileReader(f));
                } catch (FileNotFoundException ex) {
                    ex.printStackTrace();
                }
    if ( f.exists() )
		
                    try {
                      
                         FileOutputStream out = new FileOutputStream(pathOut,true);		
			
			PrintWriter miArchivo = new PrintWriter(out);
			miArchivo.write("Densidad" +"\t"); 
			miArchivo.write("Flujo" +"\t");
			
			
			miArchivo.println();
			miArchivo.close();
                        
                        System.out.println( entrada.readLine()); 
                  
                       
                        
                        String s;
                        while((s=entrada.readLine())!= null){
                            //Separar campos
                            result = s.split(",");
                            objectID = result[0];
                            System.out.println(objectID);
                            evTime = Double.valueOf(result[1]).doubleValue();
                            segment = Integer.valueOf(result[2]).intValue();
                            evPos = Double.valueOf(result[3]).doubleValue();
                            evType = Integer.valueOf(result[4]).intValue();
                            
                            if(segment == segToAnalyze) {
                                
                                if(evTime > limitPeriod){
                                    
                                    
                                    d = nD-nQ;
                                 
                                   if(nD != 0)
                                    q = nQ/nD;
                                   else
                                       q = 0;
                                    
                                    out = new FileOutputStream(pathOut,true);
                                    
                                    miArchivo = new PrintWriter(out);
                                    miArchivo.write(d +"\t");
                                    miArchivo.write(q +"\t");
                                    
                                    
                                    miArchivo.println();
                                    miArchivo.close();
                                    
                                    
                                }
                                if(evType == CE){
                                    nQ ++;
                                }else{
                                    if(evType == ALE || evType == AE){
                                        
                                        nD++;
                                    }
                                }
                                
                            }
                            
                        } 
                        System.out.println("Finished Analysis");
                        
                        
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    } 
        }
}


